import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# ============= 读取数据集 ==============
fashion_mnist = tf.keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

# 特征数据归一化
train_images = train_images/255.0
test_images = test_images/255.0
# 不需要手动对标签数据进行独热编码
# train_labels_ohe = tf.one_hot(train_labels, depth=10)
# test_labels_ohe = tf.one_hot(test_labels, depth=10)

# ============= 模型定义 ===============
# 注：以上模型也可以一次性完成
model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(512, activation=tf.nn.relu),
    # tf.keras.layers.Dense(256, activation=tf.nn.relu),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(32, activation=tf.nn.relu),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
# 输出模型摘要
model.summary()
# ================= 定义训练模式 ===================
model.compile(optimizer='adam',  # 优化器
              loss=tf.keras.losses.sparse_categorical_crossentropy,  # 损失函数
              metrics=['accuracy'])  # 评估指标

# 设置训练参数
training_epochs = 40  # 训练轮数
batch_size = 64  # 单次训练样本数

# 模型训练
train_history = model.fit(x=train_images, y=train_labels,
          validation_split=0.2,
          epochs=training_epochs,
          batch_size=batch_size,
          verbose=2)

# 训练过程指标数据
print(train_history.history)
# 训练过程指标可视化
def show_train_history(train_history, train_metric, val_metric):
    plt.plot(train_history.history[train_metric])
    plt.plot(train_history.history[val_metric])
    plt.title('Train History')
    plt.ylabel(train_metric)
    plt.xlabel('Epoch')
    plt.legend(['train', 'validation'], loc='upper left')
    plt.show()

# show_train_history(train_history, 'loss', 'val_loss')
# show_train_history(train_history, 'accuracy', 'val_accuracy')

# ================= 评估模型 ===================
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('评估模型')
print(test_loss, test_acc)

# ================= 应用模型 ===================
# print('应用模型')
# test_pred = model.predict(test_images)
# print(test_pred.shape)
# print('预测值：', np.argmax(test_pred[0]))
# print('实际值：', test_labels[0])
